#!/usr/bin/python3

# -*- coding: UTF-8 -*- 
#ct_tk.py

from tkinter import filedialog
import tkinter
from tkinter import ttk
from tkinter import messagebox
import sys
import ct_widget
import ct_core

language = 'chinese'
MODIFY = False

readonly='readonly'
relationships=('>','<','=','!','\{','\}')
mac_policy_fields=('f1','f2','f3')
mac_policies=('rw','r-','-w','--')

first_items=('f1','f2','f3')
second_items=('-','f1','f2','f3')
third_items=('-','f1','f2','f3')


# prepare func
def create_root(r):
    ''' r is Root instance, defined in ct_widget '''
    global root_window
    root_window = tkinter.Tk()

    # grid management for root window
    for cf in r.grid_management.cf_list:
        cf_func = getattr(root_window, cf[0])
        cf_func( cf[1], weight=cf[2])

    # size & title
    root_window.geometry('%sx%s+%s+%s' %(r.width, r.height, r.leftx, r.uppery))
    root_window.title(ct_widget.translate('Linx security center', language))

    # bind WM_DELETE_WINDOW
    root_window.protocol('WM_DELETE_WINDOW', root_window.quit)

    # define variables, some variables (StringVar type) must be defined
    # after Tk() be called
    define_variables()

    for w in r.widgets: create_widget(w, root_window)

    root_window.mainloop()

def get_attributes(attr_dict):
    ''' modify values in attr_dict to suit tk usage '''
    l = []
    for k, v in attr_dict.items():
        if k == 'text': l.append('%s="%s"' %(k, ct_widget.translate(v, language)))
        elif k == 'orient': l.append('%s=tkinter.%s' %(k, v))
        elif k == 'value': l.append('%s="%s"' %(k, v))
        else: l.append('%s=%s' %(k, v))
    return ','.join(l)
        
def create_widget(w, p):
    ''' create widget
 w is a widget instance in ct_widget
 p is parent widget in tk '''
    try:
        tk_func = getattr(tkinter, w.tp)
    except(AttributeError):
        tk_func = getattr(tkinter.ttk, w.tp)

    w_win=tk_func(master=p)
    s_attr = get_attributes(w.attr)

    exec('w_win.config(%s)' %(s_attr) )

    for sub_w in w.widgets:
        create_widget(sub_w, w_win)

    if 'grid_management' in dir(w):
        for cf in w.grid_management.cf_list:
            cf_func = getattr(w_win, cf[0])
            cf_func( cf[1], weight=cf[2])

    if 'grid_location' in dir(w):
        w_win.grid(w.grid_location.dict)
        if not w.display: w_win.grid_remove()

    # handle bindings
    for bd in w.bindings:
        exec('w_win.bind("%s", %s)' %(bd[0], bd[1]))

    if 'name' in dir(w):
        setattr(sys.modules[__name__], '%s_%s' %(w.tp.lower(), w.name), w_win)

    global widget_dict
    widget_dict[w_win] = w

def show_me(win):
    master = win.master
    gl     = widget_dict[win].grid_location
    siblings = master.grid_slaves(row=gl.dict['row'], column=gl.dict['column'])
    for w in siblings:
        w.grid_remove()
    win.grid()

def hide_me(win):
    win.grid_remove()
######### prepare func end

def list_2_str(l):
    mystr = ''
    for i in l:
        mystr += i
    return mystr


# main windows, 
def frame_mac_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MAC_', language))
    show_me(frame_mac)
    
def frame_mbc_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MBC_', language))
    show_me(frame_mbc)
    
def frame_itc_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#INIT_TYPIC_', language))
    show_me(frame_itc)
    
def frame_help_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#HELP_', language))
    show_me(frame_help)



# mac show and setting
def frame_subject_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MAC_SUB', language))
    show_me(frame_subject)


''' user label '''
def show_user():
    global treeview_user_defaultized
    if not treeview_user_defaultized:
        # set scroll bar
        scrollbar_user.configure(command=treeview_user.yview)
        treeview_user.configure(yscrollcommand=scrollbar_user.set)

        # set columns and headings
        treeview_user['columns'] = ('login_name', 'group_name', 'field1','field2','field3')
        treeview_user.column('#0', width=40, anchor='center')
        treeview_user.column('login_name', width=40, anchor='w')
        treeview_user.column('group_name', width=40, anchor='w')
        treeview_user.column('field1', width=70, anchor='e')
        treeview_user.column('field2', width=70, anchor='e')
        treeview_user.column('field3', width=70, anchor='e')
        treeview_user.heading('#0', text=ct_widget.translate('user id', language))
        treeview_user.heading('login_name', text=ct_widget.translate('login name', language))
        treeview_user.heading('group_name', text=ct_widget.translate('group name',language))
        treeview_user.heading('field1', text=ct_widget.translate('field1', language))
        treeview_user.heading('field2', text=ct_widget.translate('field2', language))
        treeview_user.heading('field3', text=ct_widget.translate('field3', language))

        #get default data from /etc/group, /etc/passwd, and /sys/kernel/security/linx/mac_subject_label
        ct_core.get_mac_sub_label()
        ct_core.init_user()
        for i in sorted(ct_core.d_user.keys()):
            treeview_user.insert('', 'end', ct_core.d_user[i].id, text=ct_core.d_user[i].id,\
                            values=(ct_core.d_user[i].login_name, ct_core.d_user[i].group_name, \
                            ct_core.d_user[i].field1, ct_core.d_user[i].field2, ct_core.d_user[i].field3))

        treeview_user_defaultized = True

def frame_user_show():
    root_window.title(ct_widget.translate('#MAC_SUB_USER', language))
    show_user()
    show_me(frame_user)
    show_me(frame_user_field)
    

def treeview_user_select(arg):
    idx = treeview_user.selection()
    l   = list(treeview_user.item(idx, option='values'))
    field1.set(value=l[2])
    field2.set(value=l[3])
    field3.set(value=l[4])

def treeview_user_apply():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('apply', language),\
            message=ct_widget.translate('#DOAPPLY', language)):
        return 
    ct_core.write_mac_sub_file()
    MODIFY = False

def treeview_user_clear():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('clear', language),\
            message=ct_widget.translate('#DOCLEAR', language)):
        return 
    ct_core.d_sub_label.clear()
    ct_core.write_mac_sub_file()

    # modify display
    for idx in ct_core.d_user:
        l = list(treeview_user.item(idx, option='values'))
        l[2] = l[3] = l[4] = '-'
        if idx == '-':
            l[2] = l[3] = l[4] = ''
        treeview_user.item(idx, values=l)

    treeview_user_defaultized = False
    show_user()
    MODIFY = False

def treeview_user_del():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('del', language),\
            message=ct_widget.translate('#DODELETE', language)):
        return 
    idx = treeview_user.selection()
    u = list(treeview_user.item(idx, option='text'))
    uid = list_2_str(u)

    l = list(treeview_user.item(idx, option='values'))
    if uid == '-':
        l[2] = l[3] = l[4] = ''
    else: l[2] = l[3] = l[4] = '-'
    treeview_user.item(uid, values=l)
    if uid in ct_core.d_sub_label:
        ct_core.set_mac_sub_label(uid)
    # modify display 
    field1.set(value = '')
    field2.set(value = '')
    field3.set(value = '')
    MODIFY = True

def treeview_user_modify():
    global MODIFY
    # judge whether it exceeds range
    if not ct_core.check_field(entry_field1.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field1', language), \
                                       entry_field1.get(), ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(entry_field2.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field2', language), \
                                       entry_field2.get(), ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(entry_field3.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field3', language), \
                                       entry_field3.get(), ct_widget.translate('exceeds range', language)))
        return
    # modify display
    idx = treeview_user.selection()
    l = list(treeview_user.item(idx, option='values'))
    l[2] = field1.get()
    l[3] = field2.get()
    l[4] = field3.get()
    treeview_user.item(idx, values=l)
    # modify security in core
    u = list(treeview_user.item(idx, option='text'))
    uid = list_2_str(u)
    ct_core.set_mac_sub_label(uid, l[2], l[3], l[4])
    MODIFY = True

''' process label '''
def treeview_process_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MAC_SUB_PROC', language))
    global treeview_process_defaultized
    if not treeview_process_defaultized:
        # set scroll bar
        scrollbar_process.configure(command=treeview_process.yview)
        treeview_process.configure(yscrollcommand=scrollbar_process.set)

        # set columns and headings
        treeview_process['columns'] = ('user_name', 'command', 'field1', 'field2', 'field3')
        treeview_process.column('#0', width=40, anchor='e')
        treeview_process.column('user_name', width=40, anchor='w')
        treeview_process.column('command', width=120, anchor='w')
        treeview_process.column('field1', width=60, anchor='e')
        treeview_process.column('field2', width=60, anchor='e')
        treeview_process.column('field3', width=60, anchor='e')
        treeview_process.heading('#0', text=ct_widget.translate('process id', language))
        treeview_process.heading('user_name', text=ct_widget.translate('user name', language))
        treeview_process.heading('command', text=ct_widget.translate('command', language))
        treeview_process.heading('field1', text=ct_widget.translate('field1', language))
        treeview_process.heading('field2', text=ct_widget.translate('field2', language))
        treeview_process.heading('field3', text=ct_widget.translate('field3', language))

        treeview_process_defaultized=True

    for i in treeview_process.get_children():
        treeview_process.delete(i)

    for i in ct_core.get_process():
        f1, f2, f3 = ct_core.get_process_mac(i.id)
        treeview_process.insert('', 'end', text=i.id, values=(i.user_name, i.cmd, f1, f2, f3))

    show_me(frame_process)
    hide_me(frame_user_field)


''' object--file label '''
def frame_object_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MAC_OBJ', language))
    show_me(frame_object)
    treeview_file_show()

def treeview_file_show():
    global treeview_file_defaultized
    if not treeview_file_defaultized:
        # set scroll bar
        scrollbar_file.configure(command=treeview_file.yview)
        treeview_file.configure(yscrollcommand=scrollbar_file.set)

        # set columns and headings
        treeview_file['columns'] = ('mode', 'user_name', 'group_name', 'field1',\
                'field2', 'field3', 'bypass', 'bypass_def')
        treeview_file.column('#0', width=100, anchor='center')
        treeview_file.column('mode', width=40, anchor='center')
        treeview_file.column('user_name', width=40, anchor='w')
        treeview_file.column('group_name', width=40, anchor='w')
        treeview_file.column('field1', width=60, anchor='e')
        treeview_file.column('field2', width=60, anchor='e')
        treeview_file.column('field3', width=60, anchor='e')
        treeview_file.column('bypass', width=70, anchor='e')
        treeview_file.column('bypass_def', width=70, anchor='e')
        treeview_file.heading('#0', text=ct_widget.translate('file name', language))
        treeview_file.heading('mode', text=ct_widget.translate('mode', language))
        treeview_file.heading('user_name', text=ct_widget.translate('user name', language))
        treeview_file.heading('group_name', text=ct_widget.translate('group name', language))
        treeview_file.heading('field1', text=ct_widget.translate('field1', language))
        treeview_file.heading('field2', text=ct_widget.translate('field2', language))
        treeview_file.heading('field3', text=ct_widget.translate('field3', language))
        treeview_file.heading('bypass', text=ct_widget.translate('bypassmac', language))
        treeview_file.heading('bypass_def', text=ct_widget.translate('bypass-mac-default', language))

        
        # see ct_core.construct_file_name, you will see why here transfer a list
        for i in ct_core.get_file(['/'], False) or []:
            treeview_file.insert('', 'end', '/', text=i.name, values=(i.mode,\
                    i.user, i.group, i.field1, i.field2, i.field3, i.bypass, i.bypass_def))

        # insert a dummy child, so it can be opened
        treeview_file.insert('/', 'end', text='dummy' )

        treeview_file_defaultized = True

def treeview_file_select(arg):
    idx = treeview_file.selection()
    l   = treeview_file.item(idx, option='values')
    file_field1.set(value=l[3])
    file_field2.set(value=l[4])
    file_field3.set(value=l[5])
    flg1.set(l[6])
    flg2.set(l[7])

def get_file_name():
    idx = treeview_file.selection()
    l = list()
    f_name = treeview_file.item(idx, option='text')
    l.append(f_name)
    prt  = treeview_file.parent(idx)
    while prt:
        d_name = treeview_file.item(prt, option='text')
        l.insert(0, d_name)
        prt = treeview_file.parent(prt)

    return l

def treeview_file_open(arg):
    idx = treeview_file.selection()
    for i in treeview_file.get_children(idx):
        treeview_file.delete(i)
    l = get_file_name()
    for i in ct_core.get_file(l, True) or []:
        new_idx = treeview_file.insert(idx, 'end', text=i.name, values=(i.mode,\
                i.user, i.group, i.field1, i.field2, i.field3, i.bypass, i.bypass_def) )
        if i.mode[0] == 'd':
            treeview_file.insert(new_idx, 'end', text='dummy')

def treeview_file_modify():
    # judge whether it exceeds range
    f1 = ct_core.check_field(entry_file_field1.get())
    f2 = ct_core.check_field(entry_file_field2.get())
    f3 = ct_core.check_field(entry_file_field3.get())

    if not f1:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('file_field1', language), \
                                       entry_file_field1.get(), ct_widget.translate('exceeds range', language)))
        return
    if not f2:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('file_field2', language), \
                                       entry_file_field2.get(), ct_widget.translate('exceeds range', language)))
        return
    if not f3:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('file_field3', language), \
                                       entry_file_field3.get(), ct_widget.translate('exceeds range', language)))
        return

    if f1 == '-1' : f1 = 0
    if f2 == '-1' : f2 = 0
    if f3 == '-1' : f3 = 0

    # modify display
    idx = treeview_file.selection()
    l = list(treeview_file.item(idx, option='values'))
    l[3] = f1
    l[4] = f2
    l[5] = f3
    l[6] = callCheckbutton_flg1()
    l[7] = callCheckbutton_flg2()

    treeview_file.item(idx, values=l)

    # modify sub items, if needed
    if len(treeview_file.get_children(idx)): 
        isdir = True
    else: 
        isdir = False
    dir_a = dir_attr.get()

    if dir_a != 'file' and isdir:
        for i in treeview_file.get_children(idx):
            li = list(treeview_file.item(i, option='values'))
            if len(li)>3:
                li[3] = f1
                li[4] = f2
                li[5] = f3
                li[6] =callCheckbutton_flg1()
                li[7] =callCheckbutton_flg2()
                treeview_file.item(i, values=li)
        
    # modify security in core
    if isdir:
        if dir_a == 'file' : ct_core.set_file_label(get_file_name(), l[3], l[4],\
                l[5], l[6], l[7])
        else: ct_core.set_recursion_label(get_file_name(), l[3], l[4],\
                l[5], l[6], l[7])
    else:
        ct_core.set_file_label(get_file_name(), l[3], l[4], l[5], l[6], l[7])


def callCheckbutton_flg1():
    return flg1.get()
    
def callCheckbutton_flg2():
    return flg2.get()


''' mac netlabel show and setting '''
def frame_netlabel_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MAC_NET', language))

    d = ct_core.get_mac_net_doi()
    f, s, t = ct_core.get_mac_net_cat()
    ct_core.get_mac_net_amb()

    first_item.set(value = f)
    second_item.set(value = s)
    third_item.set(value = t)

    doi.set(value = d)

    # show ambient
    global treeview_ambient_defaultized
    if not treeview_ambient_defaultized:
        # set scroll bar
        scrollbar_ambient.configure(command=treeview_ambient.yview)
        treeview_ambient.configure(yscrollcommand=scrollbar_ambient.set)

        # set columns and headings
        treeview_ambient['columns'] = ('net_field1', 'net_field2', 'net_field3')
        treeview_ambient.column('#0', width=100, anchor='w')
        treeview_ambient.column('net_field1', width=100, anchor='e')
        treeview_ambient.column('net_field2', width=100, anchor='e')
        treeview_ambient.column('net_field3', width=100, anchor='e')
        treeview_ambient.heading('#0', text=ct_widget.translate('ip', language))
        treeview_ambient.heading('net_field1', text=ct_widget.translate('net_field1', language))
        treeview_ambient.heading('net_field2', text=ct_widget.translate('net_field2', language))
        treeview_ambient.heading('net_field3', text=ct_widget.translate('net_field3', language))

        for i in sorted(ct_core.d_amb_label):
            treeview_ambient.insert('', 'end', ct_core.d_amb_label[i].ip, text=ct_core.d_amb_label[i].ip,\
                            values=(ct_core.d_amb_label[i].net_field1,\
                            ct_core.d_amb_label[i].net_field2, ct_core.d_amb_label[i].net_field3))

        treeview_ambient_defaultized=True
    show_me(frame_ambient)
    show_me(frame_netlabel)
    show_me(frame_ambient_set)


def treeview_ambient_select(arg):
    idx = treeview_ambient.selection()
    p = list(treeview_ambient.item(idx, option='text'))
    Ip = list_2_str(p)
    ip.set(value=Ip)
    l   = treeview_ambient.item(idx, option='values')
    net_field1.set(value=l[0])
    net_field2.set(value=l[1])
    net_field3.set(value=l[2])

def treeview_ambient_add():
    global MODIFY
    # judge whether it exceeds range
    if not ct_core.check_field(net_field1.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field1', language), \
                                       entry_net_field1.get(), ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(net_field2.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field2', language), \
                                       entry_net_field2.get(), ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(net_field3.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field3', language), \
                                       entry_net_field3.get(), ct_widget.translate('exceeds range', language)))
        return
    Ip = ip.get()
    Ip = ct_core.check_address(Ip)
    if not Ip:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('ip', language), \
                                       ip.get(), ct_widget.translate('exceeds range', language)))
        return
    # modify display
    idx = treeview_ambient.selection()
    p = list(treeview_ambient.item(idx, option='text'))
    Ip_select = list_2_str(p)
    if Ip == Ip_select:
        l = list(treeview_ambient.item(idx,option='values'))
        l[0] = net_field1.get()
        l[1] = net_field2.get()
        l[2] = net_field3.get()
        treeview_ambient.item(idx,values=l)
    else:
        if treeview_ambient.exists(Ip):
            treeview_ambient.delete(Ip)
        treeview_ambient.insert('','end', Ip, text=Ip, value=(net_field1.get(), net_field2.get(), net_field3.get()))
    # modify security in core
    ct_core.set_mac_net_amb(Ip, net_field1.get(), net_field2.get(), net_field3.get())
    MODIFY = True

def treeview_ambient_del():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('del', language),\
            message=ct_widget.translate('#DODELETE', language)):
        return 
    idx =treeview_ambient.selection()
    p = list(treeview_ambient.item(idx, option='text'))
    Ip = list_2_str(p)
    treeview_ambient.delete(idx)
    ct_core.set_mac_net_amb(Ip)
    MODIFY = True

def treeview_ambient_modify():
    global MODIFY
    # judge whether it exceeds range
    if not ct_core.check_field(net_field1.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field1', language), \
                                       entry_net_field1.get(), ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(net_field2.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field2', language), \
                                       entry_net_field2.get(), ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(net_field3.get()):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field3', language), \
                                       entry_net_field3.get(), ct_widget.translate('exceeds range', language)))
        return
    Ip = ip.get()
    Ip = ct_core.check_address(Ip)
    if not Ip:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('ip', language), \
                                       ip.get(), ct_widget.translate('exceeds range', language)))
        return
    # modify display
    idx = treeview_ambient.selection()
    p = list(treeview_ambient.item(idx, option='text'))
    Ip_select = list_2_str(p)
    if Ip == Ip_select:
        l = list(treeview_ambient.item(idx,option='values'))
        l[0] = net_field1.get()
        l[1] = net_field2.get()
        l[2] = net_field3.get()
        treeview_ambient.item(idx,values=l)
    else:
        if treeview_ambient.exists(Ip):
            treeview_ambient.delete(Ip)
        if Ip_select and treeview_ambient.exists(Ip_select):
            treeview_ambient.delete(Ip_select)
        else: 
        # don't select any record
            messagebox.showerror(title='Error', message='%s' %(ct_widget.translate('#DONOTSELECT', language)))
            return
        treeview_ambient.insert('','end', Ip, text=Ip, value=(net_field1.get(), net_field2.get(), net_field3.get()))
    # modify security in core
    if Ip_select in ct_core.d_amb_label: ct_core.set_mac_net_amb(Ip_select)
    ct_core.set_mac_net_amb(Ip, net_field1.get(), net_field2.get(), net_field3.get())
    MODIFY = True


def treeview_netlabel_apply():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('apply', language),\
            message=ct_widget.translate('#DOAPPLY', language)):  
        return                                                                  

    # doi modify
    doi = entry_doi.get() 
    if not ct_core.check_field(doi, 'doi'):
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('doi', language), \
                                       entry_doi.get(), ct_widget.translate('exceeds range', language)))
        return
    ct_core.write_mac_net_doi(doi)

    # categories modify
    f = first_item.get() 
    s = second_item.get() 
    t = third_item.get() 
    if not ct_core.check_net_cat(f, s, t):
        messagebox.showerror(title='Error', message='%s (%s, %s, %s) %s' %(ct_widget.translate('categories', language), \
                                       f, s, t, ct_widget.translate('error', language)))
        return
    ct_core.write_mac_net_cat(f, s, t)
    # ambient modify
    ct_core.write_mac_net_amb()
    MODIFY = False

def treeview_netlabel_clear():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('clear', language),\
            message=ct_widget.translate('#DOCLEAR', language)):  
        return                                                                  
    ip_l = list(ct_core.d_amb_label.keys())
    for  i in ip_l:
        if treeview_ambient.exists(i):
            treeview_ambient.delete(i)
        del ct_core.d_amb_label[i]
    ct_core.write_mac_net_amb()
    MODIFY = False

''' mac default label show and setting '''	
def frame_deflabel_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MAC_DEF', language))        
    show_me(frame_deflabel)

    # shwo default label
    f1,f2,f3 = ct_core.get_mac_def_label()
    def_field1.set(value=f1)
    def_field2.set(value=f2)
    def_field3.set(value=f3)
    
def treeview_default_modify():
    # judge whether it exceeds range
    f1 = def_field1.get() 
    f2 = def_field2.get() 
    f3 = def_field3.get() 
    if not ct_core.check_field(f1) or f1 == '-':
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field1', language), \
                                       f1, ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(f2) or f2 == '-':
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field2', language), \
                                       f2, ct_widget.translate('exceeds range', language)))
        return
    if not ct_core.check_field(f3) or f3 == '-':
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('field3', language), \
                                       f3, ct_widget.translate('exceeds range', language)))
        return
    # modify security in core
    ct_core.write_mac_def_file(f1, f2, f3)


''' mac policy label show and setting '''	
def treeview_mac_policy_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    global treeview_mac_policy_defaultized
    if not treeview_mac_policy_defaultized:
        # set scroll bar
        scrollbar_mac_policy.configure(command=treeview_mac_policy.yview)
        treeview_mac_policy.configure(yscrollcommand=scrollbar_mac_policy.set)

        # set columns and headings
        treeview_mac_policy['columns'] = ('relationship', 'competence')
        treeview_mac_policy.column('#0', width=100, anchor='center')
        treeview_mac_policy.column('relationship', width=100, anchor='center')
        treeview_mac_policy.column('competence', width=100, anchor='center')
        treeview_mac_policy.heading('#0', text=ct_widget.translate('field', language))
        treeview_mac_policy.heading('relationship', text=ct_widget.translate('relationship', language))
        treeview_mac_policy.heading('competence', text=ct_widget.translate('competence', language))

        treeview_mac_policy_defaultized=True

    for i in treeview_mac_policy.get_children():
        treeview_mac_policy.delete(i)

    if ct_core.d_rules_label:
        for i in ct_core.d_rules_label:
            field = i.split()[0]
            rel = i.split()[1]
            if rel == '{':
                rel = '\{'
            if rel == '}':
                rel = '\}'
            if rel == '!':
                rel = '\!'
            treeview_mac_policy.insert('', 'end', text=field, values=(rel, ct_core.d_rules_label[i]))

    show_me(frame_mac_policy)

def frame_mac_policy_show():
    root_window.title(ct_widget.translate('#MAC_MAC_POLICY', language)) 
    treeview_mac_policy_defaultized=False
    treeview_mac_policy_show()
    show_me(frame_mac_field)
    


def treeview_mac_policy_select(arg):
    idx = treeview_mac_policy.selection()
    m = list(treeview_mac_policy.item(idx, option='text'))
    mf = list_2_str(m)
    mac_policy_field.set(value=mf)
    l   = treeview_mac_policy.item(idx, option='values')
    relationship.set(value=l[0])
    mac_policy.set(value=l[1])

def treeview_mac_policy_add():
    global MODIFY
    # modify security in core
    mpf = mac_policy_field.get()
    r = relationship.get()
    p = mac_policy.get()
    if (mpf == '') or (r == '') or (p == ''):
        messagebox.showerror(title='Error', message='%s' %(ct_widget.translate('#ADDERROR', language)))
        return
    else:
        ct_core.set_mac_rules_label(mpf, r, p)
    
    # modify display
    treeview_mac_policy_defaultized=False
    # if MODIFY is True, treeview_mac_policy_show will check , 
    MODIFY = False
    treeview_mac_policy_show()
    #
    MODIFY = True

def treeview_mac_policy_del():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('del', language),\
            message=ct_widget.translate('#DODELETE', language)):
        return 
    mpf = mac_policy_field.get()
    r = relationship.get()
    ct_core.set_mac_rules_label(mpf, r)
    treeview_mac_policy_defaultized=False
    # if MODIFY is True, treeview_mac_policy_show will check , 
    MODIFY = False
    treeview_mac_policy_show()
    #
    MODIFY = True

def treeview_mac_policy_modify():
    global MODIFY
    idx = treeview_mac_policy.selection() 
    if not idx:
        # don't select any record
        messagebox.showerror(title='Error', message='%s' %(ct_widget.translate('#DONOTSELECT', language)))
        return
    # modify security in core
    mpf = mac_policy_field.get()
    r = relationship.get()
    p = mac_policy.get()
    ct_core.set_mac_rules_label(mpf, r, p)
    
    # modify display
    treeview_mac_policy_defaultized=False
    # if MODIFY is True, treeview_mac_policy_show will check , 
    MODIFY = False
    treeview_mac_policy_show()
    #
    MODIFY = True


def treeview_mac_policy_apply():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('apply', language),\
            message=ct_widget.translate('#DOAPPLY', language)):
        return 
    ct_core.write_mac_rules_file()
    treeview_mac_policy_defaultized=False
    MODIFY = False
    treeview_mac_policy_show()

def treeview_mac_policy_clear():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('clear', language),\
            message=ct_widget.translate('#DOCLEAR', language)):
        return 
    ct_core.d_rules_label.clear()
    ct_core.write_mac_rules_file()
    treeview_mac_policy_defaultized=False
    MODIFY = False
    treeview_mac_policy_show()


# mbc show and setting
def frame_mbc_policy_show():
    root_window.title(ct_widget.translate('#MBC_POLICY', language))
    mbc_policy_show()
    show_me(frame_mbc_policy_field)

def mbc_policy_show():
    global treeview_mbc_policy_defaultized
    if not treeview_mbc_policy_defaultized:
        # set scroll bar
        scrollbar_mbc_policy.configure(command=treeview_mbc_policy.yview)
        treeview_mbc_policy.configure(yscrollcommand=scrollbar_mbc_policy.set)

        # set columns and headings
        treeview_mbc_policy['columns'] = ('object', 'competence')
        treeview_mbc_policy.column('#0', width=100, anchor='w')
        treeview_mbc_policy.column('object', width=100, anchor='w')
        treeview_mbc_policy.column('competence', width=20, anchor='center')
        treeview_mbc_policy.heading('#0', text=ct_widget.translate('subject', language))
        treeview_mbc_policy.heading('object', text=ct_widget.translate('object', language))
        treeview_mbc_policy.heading('competence', text=ct_widget.translate('competence', language))

        treeview_mbc_policy_defaultized=True

    for i in treeview_mbc_policy.get_children():
        treeview_mbc_policy.delete(i)

    for i in ct_core.d_mbc_label:
        for l in ct_core.d_mbc_label[i]:
            comp = l.split(' ')[-1]
            obj = l[0:len(l)-4]
            treeview_mbc_policy.insert('', 'end', text=i, values=(obj, comp))

    show_me(frame_mbc_policy)

def callCheckbutton_r():
    return r0.get()
    
def callCheckbutton_w():
    return w0.get()

def callCheckbutton_x():
    return x0.get()

def treeview_mbc_policy_select(arg):
    idx = treeview_mbc_policy.selection()
    m = list(treeview_mbc_policy.item(idx, option='text'))
    mbc_sub = list_2_str(m)
    mbc_subject.set(value=ct_core.quote_name_add(mbc_sub))

    l = treeview_mbc_policy.item(idx, option='values')
    #mbc_object.set(value=ct_core.quote_name_add(l[0]))
    mbc_object.set(value=l[0])
    rwx = l[1]
    r0.set(rwx[0])
    w0.set(rwx[1])
    x0.set(rwx[2])

def treeview_mbc_policy_add():
    global MODIFY
    treeview_mbc_policy_modify()
    MODIFY = True

def treeview_mbc_policy_del():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('del', language),\
       message=ct_widget.translate('#DODELETE', language)): 
        return

    rel_sub = ct_core.get_real_file(entry_mbc_subject.get())
    rel_obj = ct_core.get_real_file(entry_mbc_object.get())

    if not (rel_sub and rel_obj and ct_core.set_mbc_label(rel_sub, rel_obj)):
        messagebox.showerror(title='Error', message='%s' %ct_widget.translate('#NOTDEL', language))

    # modify display
    treeview_mbc_policy_defaultized=False
    # if MODIFY is True,frame_mbc_policy_show will check , 
    MODIFY = False
    frame_mbc_policy_show()
    #
    MODIFY = True


def treeview_mbc_policy_modify():
    global MODIFY
    rel_sub = ct_core.get_real_file(entry_mbc_subject.get())
    rel_obj = ct_core.get_real_file(entry_mbc_object.get())

    if not rel_sub:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('mbc_subject', language), \
                                       entry_field1.get(), ct_widget.translate('#NOTSUB', language)))
        return
    if not rel_obj:
        messagebox.showerror(title='Error', message='%s(%s) %s' %(ct_widget.translate('mbc_object', language), \
                                       entry_mbc_object.get(), ct_widget.translate('#NOTOBJ', language)))
        return

    r = callCheckbutton_r()
    w = callCheckbutton_w()
    x = callCheckbutton_x()
    rwx = r + w + x
    # set d_mbc_label
    ct_core.set_mbc_label(rel_sub, rel_obj, rwx)

    treeview_mbc_policy_defaultized=False
    # if MODIFY is True,frame_mbc_policy_show will check , 
    MODIFY = False
    frame_mbc_policy_show()
    #
    MODIFY = True

def treeview_mbc_policy_apply():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('apply', language),\
            message=ct_widget.translate('#DOAPPLY', language)):  
        return                                                                  
    ct_core.write_mbc_file()
    treeview_mbc_policy_defaultized=False
    MODIFY = False
    frame_mbc_policy_show()

def treeview_mbc_policy_clear():
    global MODIFY
    if not messagebox.askyesno(title=ct_widget.translate('clear', language),\
            message=ct_widget.translate('#DOCLEAR', language)):  
        return                                                                  
    mbc_l = list(ct_core.d_mbc_label.keys())
    for  i in mbc_l:
        if treeview_mbc_policy.exists(i):
            treeview_mbc_policy.delete(i)
        del ct_core.d_mbc_label[i]
    ct_core.write_mbc_file()
    treeview_mbc_policy_defaultized=False
    MODIFY = False
    frame_mbc_policy_show()

''' mbc process show '''
def frame_mbc_process_show():
    global MODIFY
    # if modify, and do not 'without saving', do not show
    if MODIFY and not messagebox.askyesno(title='Warning', message=ct_widget.translate('#DONOTSAVE', language)):
        return 
    MODIFY = False
        
    root_window.title(ct_widget.translate('#MBC_PROC', language))
    global treeview_mbc_process_defaultized
    if not treeview_mbc_process_defaultized:
        # set scroll bar
        scrollbar_mbc_process.configure(command=treeview_mbc_process.yview)
        treeview_mbc_process.configure(yscrollcommand=scrollbar_mbc_process.set)

        # set columns and headings
        treeview_mbc_process['columns'] = ('user_name', 'command', 'mbc')
        treeview_mbc_process.column('#0', width=60, anchor='e')
        treeview_mbc_process.column('user_name', width=60, anchor='w')
        treeview_mbc_process.column('command', width=120, anchor='w')
        treeview_mbc_process.column('mbc', width=80, anchor='center')
        treeview_mbc_process.heading('#0', text=ct_widget.translate('process id', language))
        treeview_mbc_process.heading('user_name', text=ct_widget.translate('user name', language))
        treeview_mbc_process.heading('command', text=ct_widget.translate('command', language))
        treeview_mbc_process.heading('mbc', text=ct_widget.translate('mbc', language))

        treeview_mbc_process_defaultized=True

    for i in treeview_mbc_process.get_children():
        treeview_mbc_process.delete(i)

    for i in ct_core.get_process():
        ret = ct_core.get_process_mbc(i.id)
        if ret: ret = True
        else: ret = '-'
        treeview_mbc_process.insert('', 'end', text=i.id, values=(i.user_name, i.cmd, ret))

    show_me(frame_mbc_process)
    hide_me(frame_mbc_policy_field)

def treeview_mbc_process_select(arg):
    idx = treeview_mbc_process.selection()
    p = list(treeview_mbc_process.item(idx, option='text'))
    Pid = list_2_str(p)
    l   = list(treeview_mbc_process.item(idx, option='values'))
    hav = l[2]
    if hav == 'True':
        msg = ct_core.get_process_mbc(Pid)
    else:
        msg = "No mbc policy!"
    text_mbc_process_info.delete('1.0', 'end')
    text_mbc_process_info.insert('1.0', msg) 
    show_me(frame_mbc_process_info)
    scrollbar_mbc_process_info.configure(command=text_mbc_process_info.yview)
    text_mbc_process_info.configure(yscrollcommand=scrollbar_mbc_process_info.set)

def open_file_sub():
    file_sub = filedialog.askopenfilename(initialdir = '/')
    mbc_subject.set(value=ct_core.quote_name_add(file_sub))


def open_file_obj():
    file_obj = filedialog.askopenfilename(initialdir = '/')
    mbc_object.set(value=ct_core.quote_name_add(file_obj))

# default and typical show and setting
def frame_biba_show():
    root_window.title(ct_widget.translate('#INIT_TYPIC_BIBA', language)) 
    scrollbar_biba.configure(command=text_biba.yview)
    text_biba.configure(yscrollcommand=scrollbar_biba.set)
    text_biba.delete('1.0', 'end')
    text_biba.insert('1.0', ct_widget.translate('#BIBA', language))
    show_me(frame_biba)
		
def frame_blp_show():
    root_window.title(ct_widget.translate('#INIT_TYPIC_BLP', language))
    scrollbar_blp.configure(command=text_blp.yview)
    text_blp.configure(yscrollcommand=scrollbar_blp.set)
    text_blp.delete('1.0', 'end')
    text_blp.insert('1.0', ct_widget.translate('#BLP', language))
    show_me(frame_blp)
		
def frame_typconf_show():
    root_window.title(ct_widget.translate('#INIT_TYPIC_TYPIC', language)) 
    scrollbar_typconf.configure(command=text_typconf.yview)
    text_typconf.configure(yscrollcommand=scrollbar_typconf.set)
    text_typconf.delete('1.0', 'end')
    text_typconf.insert('1.0', ct_widget.translate('#typconf', language))
    show_me(frame_typconf)
		
def frame_defaultconf_show():
    root_window.title(ct_widget.translate('#INIT_TYPIC_DEF', language))
    scrollbar_defaultconf.configure(command=text_defaultconf.yview)
    text_defaultconf.configure(yscrollcommand=scrollbar_defaultconf.set)
    text_defaultconf.delete('1.0', 'end')
    text_defaultconf.insert('1.0', ct_widget.translate('#default', language))
    show_me(frame_defaultconf)

def biba_config_set():
    if not messagebox.askyesno(title=ct_widget.translate('set', language),\
            message=ct_widget.translate('#SETBIBA', language)):
        return 
    ct_core.set_biba_config()

			
def blp_config_set():
    if not messagebox.askyesno(title=ct_widget.translate('set', language),\
            message=ct_widget.translate('#SETBLP', language)):
        return 
    ct_core.set_blp_config()

			
def typical_config_set():
    if not messagebox.askyesno(title=ct_widget.translate('set', language),\
            message=ct_widget.translate('#SETTYPICAL', language)):
        return 
    ct_core.set_typical_config()

			
def default_config_set():
    if not messagebox.askyesno(title=ct_widget.translate('set', language),\
            message=ct_widget.translate('#SETINITIALIZE', language)):
        return 
    ct_core.set_default_config()


# help message show 
def frame_mac_introduction_show():
    root_window.title(ct_widget.translate('#HELP_MAC_INTRO', language))
    scrollbar_mac_introduction.configure(command=text_mac_introduction.yview)
    text_mac_introduction.configure(yscrollcommand=scrollbar_mac_introduction.set)
    text_mac_introduction.delete('1.0', 'end')
    text_mac_introduction.insert('1.0', ct_widget.translate('#mac_introduction', language))
    show_me(frame_mac_introduction)	

def frame_mbc_introduction_show():
    root_window.title(ct_widget.translate('#HELP_MBC_INTRO', language))  
    scrollbar_mbc_introduction.configure(command=text_mbc_introduction.yview)
    text_mbc_introduction.configure(yscrollcommand=scrollbar_mbc_introduction.set)
    text_mbc_introduction.delete('1.0', 'end')
    text_mbc_introduction.insert('1.0', ct_widget.translate('#mbc_introduction', language))
    show_me(frame_mbc_introduction) 

def frame_netlabel_introduction_show():
    root_window.title(ct_widget.translate('#HELP_NET_INTRO', language))
    scrollbar_netlabel_introduction.configure(command=text_netlabel_introduction.yview)
    text_netlabel_introduction.configure(yscrollcommand=scrollbar_netlabel_introduction.set)
    text_netlabel_introduction.delete('1.0', 'end')
    text_netlabel_introduction.insert('1.0', ct_widget.translate('#netlabel_introduction', language))
    show_me(frame_netlabel_introduction)

def frame_tool_introduction_show():
    root_window.title(ct_widget.translate('#HELP_TOOL_INTRO', language))
    scrollbar_tool_introduction.configure(command=text_tool_introduction.yview)
    text_tool_introduction.configure(yscrollcommand=scrollbar_tool_introduction.set)
    text_tool_introduction.delete('1.0', 'end')
    text_tool_introduction.insert('1.0', ct_widget.translate('#tool_introduction', language))
    show_me(frame_tool_introduction)

def define_variables():
    global field1
    field1=tkinter.StringVar()
    global field2
    field2=tkinter.StringVar()
    global field3
    field3=tkinter.StringVar()

    global file_field1
    file_field1=tkinter.StringVar()
    global file_field2
    file_field2=tkinter.StringVar()
    global file_field3
    file_field3=tkinter.StringVar()

    global mac_policy_field
    mac_policy_field=tkinter.StringVar(value='')
    global relationship
    relationship=tkinter.StringVar(value='')     
    global mac_policy
    mac_policy=tkinter.StringVar(value='')   


    global first_item
    first_item=tkinter.StringVar(value='f1')
    global second_item
    second_item=tkinter.StringVar(value='-')
    global third_item
    third_item=tkinter.StringVar(value='-')
    global doi
    doi=tkinter.StringVar()
    global ip
    ip=tkinter.StringVar()
    global net_field1
    net_field1=tkinter.StringVar()
    global net_field2
    net_field2=tkinter.StringVar()
    global net_field3
    net_field3=tkinter.StringVar()

    global def_field1
    def_field1=tkinter.StringVar()
    global def_field2
    def_field2=tkinter.StringVar()
    global def_field3
    def_field3=tkinter.StringVar()

    global follow_symlink
    follow_symlink=tkinter.StringVar(value='no')
    global dir_attr
    dir_attr=tkinter.StringVar(value='file')
    global flg1
    flg1=tkinter.StringVar()  
    global flg2
    flg2=tkinter.StringVar()    
    global r0
    r0=tkinter.StringVar(value='-') 
    global w0
    w0=tkinter.StringVar(value='-')        
    global x0
    x0=tkinter.StringVar(value='-')                       

    global mbc_subject
    mbc_subject=tkinter.StringVar()
    global mbc_object
    mbc_object=tkinter.StringVar()
    
widget_dict = dict()
treeview_user_defaultized = False
treeview_process_defaultized=False
treeview_mbc_process_defaultized=False
treeview_file_defaultized=False
treeview_mac_policy_defaultized=False
treeview_mbc_policy_defaultized=False
treeview_ambient_defaultized=False


ct_core.get_mbc_label()
ct_core.get_mac_rules_label()
ct_core.get_mac_net_amb()
ct_core.init_user()
